/**
 * @file epd_hal.h
 * @brief Hardware Abstraction Layer (HAL) for EPD driver on ESP32.
 * @details Provides SPI configuration, timing utilities, and basic GPIO controls.
 *          CPOL/CPHA are documented and stored, but may be constrained by underlying SDK.
 *          MISRA C style and Doxygen annotations are used.
 */
#ifndef EPD_HAL_H
#define EPD_HAL_H

#include <stdint.h>
#include <stdbool.h>

/** Error codes for EPD HAL */
typedef enum {
    EPD_OK = 0,
    EPD_ERR_PARAM = -1,
    EPD_ERR_HW = -2,
    EPD_ERR_TIMEOUT = -3,
    EPD_ERR_UNSUPPORTED = -4
} epd_err_t;

/** SPI configuration structure */
typedef struct {
    uint32_t freq_hz;      /**< SPI clock frequency in Hz (target: 8 MHz, ±2%) */
    uint8_t mode;          /**< SPI mode 0..3. Mode 0 => CPOL=0, CPHA=0 */
    uint8_t cpol;          /**< Clock polarity (CPOL): 0 or 1 */
    uint8_t cpha;          /**< Clock phase (CPHA): 0 or 1 */
    bool msb_first;        /**< Bit order: true for MSB first */
    bool use_dma;          /**< Enable DMA usage if supported */
} epd_spi_config_t;

/** HAL runtime context holding applied configuration */
typedef struct {
    epd_spi_config_t spi_cfg;
} epd_hal_ctx_t;

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief Initialize HAL SPI according to provided configuration.
 * @param ctx Pointer to HAL context to store applied config.
 * @param cfg Desired SPI configuration.
 * @return epd_err_t EPD_OK on success, error otherwise.
 */
epd_err_t epd_hal_init_spi(epd_hal_ctx_t *ctx, const epd_spi_config_t *cfg);

/**
 * @brief Write one command byte over SPI.
 * @param cmd Command byte.
 * @return epd_err_t
 */
epd_err_t epd_hal_spi_write_command(uint8_t cmd);

/**
 * @brief Write one data byte over SPI.
 * @param data Data byte.
 * @return epd_err_t
 */
epd_err_t epd_hal_spi_write_data(uint8_t data);

/**
 * @brief Delay in milliseconds.
 * @param ms Milliseconds to delay.
 */
void epd_hal_delay_ms(uint32_t ms);

/**
 * @brief Read BUSY pin (true if busy).
 * @return bool Busy state.
 */
bool epd_hal_read_busy(void);

/**
 * @brief Toggle reset line with typical EPD timing.
 * @return epd_err_t
 */
epd_err_t epd_hal_reset_sequence(void);

#ifdef __cplusplus
}
#endif

#endif /* EPD_HAL_H */